/**
 * 
 */
package xiaojian.toolkit.bean;

import java.lang.reflect.Field;
import java.util.concurrent.Callable;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import xiaojian.toolkit.bean.annotation.BeanAttribute;
import xiaojian.toolkit.util.FieldUtils;
import xiaojian.toolkit.util.SimpleCache;

/**
 * @author hp
 * 
 */
public class BeanUtils {

	private static final Logger logger = LoggerFactory
			.getLogger(BeanUtils.class);

	private static SimpleCache<Class<?>, Field[]> beanFieldsCache = new SimpleCache<Class<?>, Field[]>();

	public static Field[] getBeanFieldsOf(final Class<?> beanType) {
		return beanFieldsCache.get(beanType, new Callable<Field[]>() {

			public Field[] call() throws Exception {
				return FieldUtils.getAnnotationFieldsOf(beanType,
						BeanAttribute.class);
			}
		});
	}

	public static void checkRequired(Object bean) {
		if (null == bean) {
			return;
		}

		Field[] fields = getBeanFieldsOf(bean.getClass());
		for (Field field : fields) {
			BeanAttribute attr = field.getAnnotation(BeanAttribute.class);

			field.setAccessible(true);

			if (null != attr && attr.required()
					&& !field.getType().isPrimitive()) {
				Object value = null;
				try {
					value = field.get(bean);
				} catch (IllegalArgumentException e) {
					logger.error("checkRequired:", e);
				} catch (IllegalAccessException e) {
					logger.error("checkRequired:", e);
				}
				if (null == value) {
					throw new RuntimeException("required field missing ["
							+ field + "]");
				}

				String strValue = String.valueOf(value);
				if (!attr.allowEmpty() && StringUtils.isEmpty(strValue)) {
					throw new RuntimeException("field [" + field
							+ "] is empty.");
				}

				if (!attr.allowBlank() && StringUtils.isBlank(strValue)) {
					throw new RuntimeException("field [" + field
							+ "] is blank.");
				}
			}
		}
	}
}
